﻿#include"msave.h"
#include<stddef.h>
#include<malloc.h>
#include<stdlib.h>
MValue MCreateValue(int size)
{
	MValue re;
	re.value = NULL;
	re.len = size;
	return re;
}
static MValue MCreateErrValue()
{
	MValue re;
	re.type = VTYPE_ERR;
	return re;
}
bool MMallocValue(int size, MValue* val)
{
	if (val == NULL)
		return false;
	val->value = malloc(size);
	val->len = size;
	return true;
}
void MDeletValue(MValue* val)
{
	free(val->value);
	val->len = 0;
}
bool MSetValue(void* buf, int type, MValue* val)
{
	void* n = buf;
	if (val == NULL)
		return false;
	if (val->len < sizeof(buf))
	{
		//先扩容
		free((int*)val->value);
		val->value = malloc(sizeof(buf));
		val->len = sizeof(buf);
		if (val->value == NULL)
			return false;
	}
	val->value = n;
	val->type = type;
	return true;
}
MStack MCreateStack(int size)
{
	MStack ms;
	ms.cp = 0;
	ms.size = size;
	ms.stack = (int*)malloc(sizeof(int) * size);
	return ms;
}
void* MGetValue(MValue val)
{
	if (val.type == VTYPE_INT)
		return (int)val.value;
	else if (val.type == VTYPE_STR)
		return (char*)val.value;
	else if (val.type == VTYPE_DOUBLE)
		return (double*)val.value;
	else return (int)val.value;
}
static bool MPrepareMalloc(MVarList* vlist)
{
	//搜索变量表，并将变量表的cur位置重定向
	//没有空间返回假

	for (int i = 0; i < vlist->max_size; i++)
	{
		if (vlist->v_list[i].state != VSTATE_USED)//只要是不被占用的变量位置立即重定向
		{
			vlist->cur = i;
			return true;
		}
	}
	return false;
}
MVarList MCreateVariableList(int size)
{
	MVarList re;
	re.max_size = size;
	re.cur = 0;
	re.v_list = (MVar*)malloc(sizeof(MVar) * size);
	return re;
}
int MMallocVar(MVarList* vlist, int lock_sta_addr)
{
	if (vlist == NULL || vlist->cur >= vlist->max_size)
		return -1;
	if (vlist->v_list[vlist->cur].state != VSTATE_USED)
	{
		//如果当前位置没有被占用，则直接向后分配
		vlist->v_list[vlist->cur].state = VSTATE_USED;
		vlist->v_list[vlist->cur].sta_addr = lock_sta_addr;
		vlist->v_list[vlist->cur].value = MCreateValue(1);
		vlist->cur++;
		return vlist->cur - 1;
	}
	else if (MPrepareMalloc(vlist))
	{
		//如果找到碎片化空间
		vlist->v_list[vlist->cur].state = VSTATE_USED;
		vlist->v_list[vlist->cur].sta_addr = lock_sta_addr;
		vlist->v_list[vlist->cur].value = MCreateValue(1);
		vlist->cur++;
		return vlist->cur - 1;
	}
	else return -1;//没有空余空间分配
}
MValue MGetVar(MVarList vlist, int addr)
{
	if (addr >= vlist.max_size)
		return MCreateErrValue();
	return vlist.v_list[addr].value;
}
bool MSetVar(MVarList* vlist, int idx, MValue v)
{
	if (vlist == NULL || idx >= vlist->max_size)
		return false;
	vlist->v_list[idx].value = v;
	return true;
}
